﻿using System;
using System.Data;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Data.SqlServerCe;
using OverStore.Runtime;
using OverStore.Runtime.Storage;
using OverStore.Runtime.Logger;
using OverStore.TutorialAsTest.UnitTest.Configuration.Rdbms.InstanceStorage;
using OverStore.TutorialAsTest.UnitTest.Configuration.Mocks;
using OverStore.TutorialAsTest.UnitTest.Components;
using OverStore.Runtime.PersistenceServiceProvider;
using OverStore.Sql;
using OverStore.Runtime.ObjectRepository.IdentifierProvider;
using OverStore.Runtime.ObjectRepository.Mapping;
using OverStore.Runtime.ObjectRepository.Reader;


namespace OverStore.TutorialAsTest.UnitTest.Configuration.ObjectReadVariant
{
    /// <summary>
    /// Summary description for ObjectReadVariant_Test
    /// </summary>
    [TestClass]
    public class ObjectReadVariant_Test
    {
        private ParameterizedReader<SimpleClass, Guid, SimpleClass> CreateSimpleClassReadCommand(string connectionString, IPersistenceServiceProvider persistenceServiceProvider)
        {
            var dataSource = new AdoNetStorage<SqlCeConnection>(connectionString, ProcessOpenedReadersMode.ThrowException, DummyLogger.Value, new SqlServerCeFormatting(), new OverStore.Scoping.Manager.OperationScopeManager());
            return new ParameterizedReader<SimpleClass, Guid, SimpleClass>(
                new DelegateIdentifierProvider<Guid>(d => d.GetGuid("ID")),
                persistenceServiceProvider,
                new DelegateMapper<SimpleClass>((item, name, locator) => null,
                    (record, item, locator) =>
                    {
                    }),
                new AdoNetCommand("SELECT ID FROM SimpleClass", CommandType.Text,
                    new AdoNetParameter[] { }, AdoCommandResultType.DataReaderResultSet, DummyLogger.Value),
                    dataSource,
                    null,
                    false);
        }

        ParameterizedReader<SimpleClass, Guid, SimpleClass> CreateParameterizedReadCommand(string connectionString, IPersistenceServiceProvider persistenceServiceProvider)
        {
            var dataSource = new AdoNetStorage<SqlCeConnection>(
                connectionString,
                ProcessOpenedReadersMode.ThrowException,
                DummyLogger.Value,
                new SqlServerCeFormatting(),
                new OverStore.Scoping.Manager.OperationScopeManager());
            var result = new ParameterizedReader<SimpleClass, Guid, SimpleClass>(
                new DelegateIdentifierProvider<Guid>(r => r.GetGuid("ID")),
                persistenceServiceProvider,
                new DelegateMapper<SimpleClass>(
                    (item, name, locator) => name == "ID" ? (object)item.ID : null,
                    (data, item, locator) =>
                    {
                    }),
                new AdoNetCommand(
                    "SELECT ID FROM SimpleClass WHERE ID = @ID", CommandType.Text,
                    new[] { new AdoNetParameter("ID", false, DbType.Guid) }, AdoCommandResultType.DataReaderResultSet, DummyLogger.Value),
                dataSource,
                null,
                false);

            return result;
        }

        private static List<Guid> IdSet = new List<Guid>()
        {
           new Guid("508538e3-111b-4fde-a714-20fb78205662"),
           new Guid("f30c02ce-33fd-4dda-8228-500609c8ee7b"),
           new Guid("64ca46ee-de9e-4388-9a79-96f1a062fc52"),
           new Guid("8f10f298-b4a3-4686-ab7e-e565f8bee70a")
        };


        [TestMethod]
        public void ObjectReadVariant_ReadSimpleClass()
        {
            var connectionString = TestHelper.CreateTestDbCopyAndBuildConnectionString();
            var registryLocator = new DefaultRegistryLocator()
                    .AddRegistry(
                            new FunctionalRegistry<SimpleClass, Guid>(
                                (id, record) =>
                                {
                                    if (IdSet.Contains(id))
                                        return new SimpleClass()
                                        {
                                            ID = id
                                        };
                                    throw new InvalidOperationException("Invalid id");
                                }, item => item.ID));

            var readCommand = CreateSimpleClassReadCommand(connectionString, registryLocator);

            var list = readCommand.ExecuteRead(new SimpleClass()).ToList();
            Assert.AreEqual(IdSet.Count, list.Count);
        }

        [TestMethod]
        public void ObjectReadVariant_ParameterizedCommand()
        {
            var connectionString = TestHelper.CreateTestDbCopyAndBuildConnectionString();
            var registryLocator = new DefaultRegistryLocator()
                      .AddRegistry(new FunctionalRegistry<SimpleClass, Guid>(
                              (id, data) => new SimpleClass
                              {
                                  ID = id
                              }, item => item.ID));
            var readCommand = CreateParameterizedReadCommand(connectionString, registryLocator);
            var parameter = new SimpleClass()
            {
                ID = IdSet[new Random().Next(IdSet.Count)]
            };



            var list = readCommand.ExecuteRead(parameter).ToList();
            Assert.AreEqual(1, list.Count);
            Assert.AreEqual(parameter.ID, list[0].ID);
        }
    }
}
